/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package InstanciaJogo.FasesJogo;

import ClassesListas.ImagensApresentadasSubFase;
import ClassesUnicas.ImagemApresentadaSubFase;
import DAO.DAOInstanciaSubFase;
import DAO.MySQL.DAOInstanciaSubFaseMySQL;
import InstanciaJogo.InstanciaJogoSwing;
import java.awt.Image;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;

/**
 * Estatica
 *
 * Versao 1.0
 *
 * Data Criação 07/08/2013
 *
 * @author Igor
 */
public class Estatica implements InstanciaSubFase {

    //Atributos
    private long idInstanciaSubFase;
    private long subFase;
    private ImagensApresentadasSubFase imagensFase;
    private int indiceImagemApresentada;
    private int quantidadeImagensParaAvaliar;
    private Timer timerApresentarImagem;
    private int quantidadeImagensAvaliadasCorretamente;

    //DAO
    private DAOInstanciaSubFase subFaseDAO;

    //Construtor
    public Estatica(long subFase) {
        this.imagensFase = new ImagensApresentadasSubFase();
        this.subFase = subFase;
        this.indiceImagemApresentada = 0;
        this.quantidadeImagensParaAvaliar = 0;
        this.subFaseDAO = new DAOInstanciaSubFaseMySQL();
        this.quantidadeImagensAvaliadasCorretamente = 0;
    }

    //Getters e Setters
    @Override
    public long getIdInstanciaSubFase() {
        return idInstanciaSubFase;
    }

    @Override
    public void setIdInstanciaSubFase(long idInstanciaSubFase) {
        this.idInstanciaSubFase = idInstanciaSubFase;
    }

    @Override
    public long getSubFase() {
        return subFase;
    }

    @Override
    public void setSubFase(long subFase) {
        this.subFase = subFase;
    }

    @Override
    public ImagensApresentadasSubFase getImagensFase() {
        return imagensFase;
    }

    @Override
    public void setImagensFase(ImagensApresentadasSubFase imagensFase) {
        this.imagensFase = imagensFase;
    }

    @Override
    public int getIndiceImagemApresentada() {
        return indiceImagemApresentada;
    }

    @Override
    public void setIndiceImagemApresentada(int indiceImagemApresentada) {
        this.indiceImagemApresentada = indiceImagemApresentada;
    }

    @Override
    public int getQuantidadeImagensParaAvaliar() {
        return quantidadeImagensParaAvaliar;
    }

    @Override
    public void setQuantidadeImagensParaAvaliar(int quantidadeImagensParaAvaliar) {
        this.quantidadeImagensParaAvaliar = quantidadeImagensParaAvaliar;
    }

    @Override
    public void setQuantidadeImagensParaAvaliar() {
        this.quantidadeImagensParaAvaliar = getImagensFase().getImagens().size();
    }

    /**
     * @return the timerApresentarImagem
     */
    public Timer getTimerApresentarImagem() {
        return timerApresentarImagem;
    }

    /**
     * @param timerApresentarImagem the timerApresentarImagem to set
     */
    public void setTimerApresentarImagem(Timer timerApresentarImagem) {
        this.timerApresentarImagem = timerApresentarImagem;
    }

    @Override
    public int getQuantidadeImagensAvaliadasCorretamente() {
        return quantidadeImagensAvaliadasCorretamente;
    }

    @Override
    public void setQuantidadeImagensAvaliadasCorretamente(int quantidadeImagensAvaliadasCorretamente) {
        this.quantidadeImagensAvaliadasCorretamente = quantidadeImagensAvaliadasCorretamente;
    }

    @Override
    public DAOInstanciaSubFase getSubFaseDAO() {
        return subFaseDAO;
    }

    @Override
    public void setSubFaseDAO(DAOInstanciaSubFase subFaseDAO) {
        this.subFaseDAO = subFaseDAO;
    }

    //Outros metodos
    @Override
    public ImagemApresentadaSubFase imagemApresentadaAtual() {
        //-1 pq o indice sempre estara uma posição a mais
        return this.imagensFase.getImagens().get(this.getIndiceImagemApresentada() - 1);
    }

    @Override
    public ImagemApresentadaSubFase retornaProximaImagemApresentada() {
        ImagemApresentadaSubFase imagemRetorno = null;

        if (this.getQuantidadeImagensParaAvaliar() > 0) {
            imagemRetorno = selecionaProximaImagemApresentada();

            //Enquanto a imagem nao for uma imagem ja avaliada, pois ele repete ate que se avalie tds as expressoes
            while (imagemRetorno.getIdExpressaoResposta() != null
                    //&& this.quantidadeImagensAvaliadas < (this.imagensFase.getImagens().size())) {
                    && this.getQuantidadeImagensParaAvaliar() > 0) {
                imagemRetorno = selecionaProximaImagemApresentada();
            }
        }
        return imagemRetorno;
    }

    @Override
    public ImagemApresentadaSubFase selecionaProximaImagemApresentada() {
        ImagemApresentadaSubFase imagemRetorno;
        if (this.getQuantidadeImagensParaAvaliar() > 0
                && this.getIndiceImagemApresentada() >= this.getImagensFase().getImagens().size()) {
            this.setIndiceImagemApresentada((int) (0));
        }

        imagemRetorno = this.imagensFase.getImagens().get(this.getIndiceImagemApresentada());
        this.setIndiceImagemApresentada((int) (this.getIndiceImagemApresentada() + 1));

        return imagemRetorno;
    }

    @Override
    public void apresentarImage(InstanciaJogoSwing instanciaJogo, boolean jogoPausado) {
        ImagemApresentadaSubFase imagemApresentada;
        int largura = instanciaJogo.getLabelImagem().getWidth();
        int altura = instanciaJogo.getLabelImagem().getHeight();
        int imagensApresentadas = 0;

        //So apresenta a imagem se nao estiver apresentando imagens atualmente
        //if (instanciaJogo.getLabelImagem().getIcon() == null) {
        if (!instanciaJogo.getLabelImagem().equals("imagemRosto")) {
            if(jogoPausado){
                imagemApresentada = imagemApresentadaAtual();
            }else{
                imagemApresentada = retornaProximaImagemApresentada();
                this.setQuantidadeImagensParaAvaliar(this.getQuantidadeImagensParaAvaliar() - 1);
            }

            imagensApresentadas = (this.getImagensFase().getImagens().size() - this.getQuantidadeImagensParaAvaliar());

            ImageIcon ig = new ImageIcon(imagemApresentada.getDiretorio().toString());
            //Amplia a imagem fazendo-a ocupar todo o JLabel
            instanciaJogo.getLabelImagem().setIcon(new ImageIcon(ig.getImage().getScaledInstance(largura, altura, Image.SCALE_DEFAULT)));
            instanciaJogo.atualizarLabel(instanciaJogo.getLabelImagem());
            
            instanciaJogo.getLabelStatus().setText("Fase: " + instanciaJogo.getFase() + "." + getSubFase()
                    + "     Imagem Apresentada: " + imagensApresentadas + "/" + this.getImagensFase().getImagens().size());
            instanciaJogo.atualizarLabel(instanciaJogo.getLabelStatus());
            
            if(instanciaJogo.getModoJogo() != 1){
                imagemApresentada.gravaImagemApresentadaSubFase(this.idInstanciaSubFase);
            }

            this.setTimerApresentarImagem(new Timer());
            this.getTimerApresentarImagem().schedule(new RemindTaskA(instanciaJogo, this.getTimerApresentarImagem(), instanciaJogo.getTempoApresentacaoImagens()), 0, 1 * 1000);
        }
    }

    @Override
    public boolean avaliarImagemEstatica(int idExpressao, long idModoJogo) {
        boolean flag = false;

        //Cancelo o timer pois ja avaliei, entao a troca de imagem nao sera por tempo e sim realizada neste metodo
        if (this.getTimerApresentarImagem() != null) {
            this.getTimerApresentarImagem().cancel();
        }

        if (this.imagemApresentadaAtual().getIdExpressaoResposta() == null) {
            //this.setQuantidadeImagensParaAvaliar(this.getQuantidadeImagensParaAvaliar() - 1);
            long idExpressao1 = this.imagemApresentadaAtual().getIdExpressao();
            this.imagemApresentadaAtual().setIdExpressaoResposta(idExpressao);
            if (idExpressao1 == idExpressao) {
                flag = true;
                setQuantidadeImagensAvaliadasCorretamente(getQuantidadeImagensAvaliadasCorretamente() + 1);
            }
            //So grava a avaliacao se nao estiver no Treinamento
            if (idModoJogo != 1) {
                this.imagemApresentadaAtual().gravaImagemApresentadaSubFase(this.idInstanciaSubFase);
            }
        }

        return flag;
    }

    @Override
    public long gravaInstanciaSubFase(long idJogo) {
        return this.getSubFaseDAO().gravaInstanciaSubFase(idJogo, 1, getSubFase());
    }

    @Override
    public long buscaPorcentagemAcerto() {
        return (this.quantidadeImagensAvaliadasCorretamente * 100 / getImagensFase().getImagens().size());
        //return this.getSubFaseDAO().buscaPorcentagemAcerto(this.idInstanciaSubFase);
    }

    class RemindTaskA extends TimerTask {

        private int segundos;
        private InstanciaJogoSwing instanciaJogo = null;
        private Timer timer = null;

        public RemindTaskA(InstanciaJogoSwing jogo, Timer timer, int tempoEspera) {
            this.segundos = tempoEspera;
            this.instanciaJogo = jogo;
            this.timer = timer;
        }

        @Override
        public void run() {
            if (this.segundos == 0) {
                this.timer.cancel();
                timerApresentarImagem.cancel();
                this.instanciaJogo.getLabelImagem().setIcon(null);
                this.instanciaJogo.atualizarLabel(this.instanciaJogo.getLabelImagem());
                this.instanciaJogo.apresentaTransacaoImagens();
            }
            segundos--;
        }
    }
}
